/*
 * Copyright (C) 2004-2006 nickyb@users.sourceforge.net
 * 
 * This file is part of FreeQueryBuilder (http://querybuilder.sourceforge.net)
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

package net.sourceforge.querybuilder;

import java.awt.Frame;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.ListIterator;

import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

public class DiagramLoader extends JDialog implements Runnable
{
	private JLabel message;
	
	private QueryDiagram diagram;
	private QueryTokens.Table table;
	
	private DiagramLoader(QueryDiagram diagram, QueryTokens.Table table)
	{
		super((Frame)SwingUtilities.getAncestorOfClass(Frame.class, diagram.builder));
		
		this.setModal(true);
		this.setSize(275,55);
		this.setTitle("wait...");
		this.setResizable(false);
		this.setLocationRelativeTo(diagram.builder);
		this.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
				
		this.getContentPane().add(message=new JLabel("",JLabel.CENTER));
		
		this.diagram = diagram;
		this.table = table;
	}
	
	public void show()
	{
		new Thread(this).start();
		super.show();
	}
	
	public void run()
	{
		try
		{
			addTable(table);
		}
		catch(SQLException sqle)
		{
			System.out.println("[ DiagramLoader::run ]\n" + sqle);
		}
		finally
		{
			this.dispose();
		}
	}
	
	public static void run(QueryDiagram diagram, QueryTokens.Table table)
	{
		new DiagramLoader(diagram,table).show();
	}
	
	private void addTable(QueryTokens.Table table)
		throws SQLException
	{
		message.setText("loading: " + table.toString(false,false));
		
		for(int i=0; diagram.find(table)!=null; i++)
		{
			String alias = table.getName() + "_" + (char)(65 + i);
			table.setAlias(alias);
		}
		
		DiagramEntity item = creatEntity(table);
		diagram.add(item);
	}
	
	private DiagramEntity creatEntity(QueryTokens.Table table)
		throws SQLException
	{
		DiagramEntity item = new DiagramEntity(table);
		item.setEnabled(diagram.builder.getConnection()!=null);
		
		if(diagram.builder.getConnection()!=null)
		{
			DatabaseMetaData dbmetadata = diagram.builder.getConnection().getMetaData();
			Hashtable primary = this.getPrimaryKeys(dbmetadata,item);
			
			String catalog = table.getSchema() == null ? null : dbmetadata.getConnection().getCatalog();
			ResultSet rsColumns = dbmetadata.getColumns(catalog, item.querytoken.getSchema(), item.querytoken.getName(), "%");
			while(rsColumns.next())
			{
				String columnName = rsColumns.getString(4).trim();
				
				String typeName = rsColumns.getString(6);
				int size = rsColumns.getInt(7);
				String nullable = rsColumns.getString(18);
				
				String infos = "type:" + typeName + "; size:" + size + "; nullable:" + nullable;
				
				DiagramEntity.Field field = item.addField(columnName, primary.containsKey(columnName),size,infos);
				diagram.builder.clauses.addColumn(field.querytoken.toString(QueryBuilder.useIdentifierQuote,false));
			}
			rsColumns.close();
		}
		item.pack();
		
		return item;
	}
	
	private Hashtable getPrimaryKeys(DatabaseMetaData dbmetadata, DiagramEntity item)
	{
		Hashtable primary = new Hashtable();
		
		try
		{
			String catalog = item.querytoken.getSchema() == null ? null : dbmetadata.getConnection().getCatalog();			
			ResultSet rsPK = dbmetadata.getPrimaryKeys(catalog, item.querytoken.getSchema(), item.querytoken.getName());		
			while(rsPK.next())
				primary.put(rsPK.getString(4).trim(), rsPK.getString(6));
			rsPK.close();
		}
		catch (SQLException sqle)
		{
			System.out.println("[ DiagramLoader::getPrimaryKeys ]\n" + sqle);
		}
		finally
		{
			return primary;
		}
	}	
}